package com.buaa.service.impl;

import com.buaa.model.dto.Link;
import com.buaa.model.dto.Node;
import com.buaa.model.dto.Relation;
import com.buaa.model.solr.Paper;
import com.buaa.model.solr.Person;
import com.buaa.repository.solr.PaperSolrRepository;
import com.buaa.repository.solr.PersonSolrRepository;
import com.buaa.service.PersonService;
import com.buaa.util.SortUtil;
import com.buaa.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * Created by DELL on 2018/4/12.
 */
@Service
public class PersonServiceImpl implements PersonService {

    @Autowired
    PaperSolrRepository paperSolrRepository;

    @Autowired
    PersonSolrRepository personSolrRepository;

    @Override
    public Relation getPaperRelationByNameAndOrganization(String name,String organization) {
        //这里查询该人物的所有论文
        PageRequest pageRequest = new PageRequest(0,999);
        List<Paper> paperList = new ArrayList<>();
        if(organization == null || organization.equals("")){
            paperList = paperSolrRepository.findPaperListByAuthor(name,pageRequest);
        }else{
            paperList = paperSolrRepository.findPaperListByAuthorAndOrg(name,organization,pageRequest);
        }

        Map<String, Double> nameAndWeight = new HashMap<>();

        for(Paper paper:paperList){
            for(String nameAndOrganization : paper.getAuthor_organizations()){
                if(StringUtil.HasDigit(nameAndOrganization)) continue;
                if(nameAndWeight.get(nameAndOrganization)==null){
                    nameAndWeight.put(nameAndOrganization,1.0);
                }else{
                    nameAndWeight.put(nameAndOrganization,nameAndWeight.get(nameAndOrganization)+1);
                }
            }
        }

        nameAndWeight = SortUtil.sortByValue(nameAndWeight,20);

        Relation relation = new Relation();
        List<Node>nodes = new ArrayList<>();
        Node mainNode = new Node();
        mainNode.setCategory(0);
        mainNode.setName(name+","+organization);
        mainNode.setValue(15);
        nodes.add(mainNode);
        for (Map.Entry<String, Double> entry : nameAndWeight.entrySet()) {
            Node node = new Node();
            node.setCategory(1);
            node.setValue(entry.getValue()/2);
            node.setName(entry.getKey());
            nodes.add(node);
        }

        Map<String,Double> nameAndLink = new HashMap<>();
        for(Paper paper:paperList){
            for(String nameAndOrganization1 : paper.getAuthor_organizations()){
                for(String nameAndOrganization2 : paper.getAuthor_organizations()){
                    //if((name+","+organization).equals(nameAndOrganization1) || (name+","+organization).equals(nameAndOrganization2)){
                        if(! nameAndOrganization1.equals(nameAndOrganization2) && nameAndLink.get(nameAndOrganization1+":"+nameAndOrganization2) == null && nameAndLink.get(nameAndOrganization2+":"+nameAndOrganization1) == null){
                            nameAndLink.put(nameAndOrganization1+":"+nameAndOrganization2,1.0);
                        }else if(nameAndLink.get(nameAndOrganization1+":"+nameAndOrganization2) != null){
                            nameAndLink.put(nameAndOrganization1+":"+nameAndOrganization2,nameAndLink.get(nameAndOrganization1+":"+nameAndOrganization2)+1);
                        }else if(nameAndLink.get(nameAndOrganization2+":"+nameAndOrganization1) != null){
                            nameAndLink.put(nameAndOrganization2+":"+nameAndOrganization1,nameAndLink.get(nameAndOrganization2+":"+nameAndOrganization1)+1);
                        }
                    //}

                }
            }
        }

        //nameAndLink = SortUtil.sortByValue(nameAndLink,100);

        List<Link> links = new ArrayList<>();
        for (Map.Entry<String, Double> entry : nameAndLink.entrySet()) {
            String key = entry.getKey();
            String[] nameTwo = key.split(":");
            Link link = new Link();
            link.setSource(nameTwo[0]);
            link.setTarget(nameTwo[1]);
            link.setName("");
            link.setWeight(entry.getValue());
            links.add(link);
        }

        relation.setNodes(nodes);
        relation.setLinks(links);

        return relation;
    }

    @Override
    public Map<Integer,Integer> getPaperChatByNameAndOrganization(String name, String organization) {

        //这里查询该人物的所有论文
        PageRequest pageRequest = new PageRequest(0,999);
        List<Paper> paperList = new ArrayList<>();
        if(organization == null || organization.equals("")){
            paperList = paperSolrRepository.findPaperListByAuthor(name,pageRequest);
        }else{
            paperList = paperSolrRepository.findPaperListByAuthorAndOrg(name,organization,pageRequest);
        }

        Map<Integer,Integer> yearAndCount = new HashMap<>();

        for(Paper paper:paperList){
            int year = paper.getYear();
            if(yearAndCount.get(year)==null){
                yearAndCount.put(year,1);
            }else{
                yearAndCount.put(year,yearAndCount.get(year)+1);
            }

        }

        return yearAndCount;
    }

    @Override
    public List<Person> findPersonListByName(String name) {
        Sort sort = new Sort(Sort.Direction.DESC, "base_score_i");
        List<Person> personList = personSolrRepository.findPersonListByName(name,sort);
        List<Person> personList_new = new ArrayList<>();
        Map<String,Integer> nameAndOrgMap = new HashMap<>();
        for(Person person:personList){
            if(nameAndOrgMap.get(person.getName()+":"+person.getOrganization()) == null){
                nameAndOrgMap.put(person.getName()+":"+person.getOrganization(),1);
                personList_new.add(person);
            }
        }
        return personList_new;
    }

    @Override
    public Person findPersonByNameAndOrg(String name, String organization) {
        Sort sort = new Sort(Sort.Direction.DESC, "base_score_i");
        Person person = personSolrRepository.findPersonByNameAndOrg(name,organization,sort);
        return person;
    }
}
